package xxl.robotlegs.extensions.mediatormap.impl 
{
	import flash.display.DisplayObject;
	import flash.utils.Dictionary;
	import xxl.robotlegs.extensions.mediatormap.api.IMediatorMapping;
	import xxl.robotlegs.extensions.viewmanager.api.IViewHandler;
	
	/**
	 * ...
	 * @author XXL
	 */
	public class MediatorViewHandler implements IViewHandler 
	{
		private const _mappings:Array = [];
		private var _knownMappings:Dictionary = new Dictionary(true);
		private var _factory:MediatorFactory;
		
		public function MediatorViewHandler(factory:MediatorFactory) 
		{
			_factory = factory;
		}
		
		public function addMapping(mapping:IMediatorMapping):void
		{
			const index:int = _mappings.indexOf(mapping);
			if (index >= 0)
			{
				return ;
			}
			_mappings.push(mapping);
			flushCache();
		}
		
		public function removeMapping(mapping:IMediatorMapping):void
		{
			const index:int = _mappings.indexOf(mapping);
			if (index < 0)
			{
				return ;
			}
			_mappings.splice(index, 1);
			flushCache();
		}
		
		public function handleItem(item:Object, type:Class):void
		{
			const interestedMappings:Array = getInterestedMappingsFor(item, type);
			if (interestedMappings)
			{
				_factory.createMediators(item, type, interestedMappings);
			}
		}
		
		//----------private
		
		private function flushCache():void
		{
			_knownMappings = new Dictionary(true);
		}
		
		private function getInterestedMappingsFor(item:Object, type:Class):Array
		{
			if (_knownMappings[type] === false)
			{
				return null;
			}
			if (_knownMappings[type] == undefined)
			{
				_knownMappings[type] = false;
				const len:int = _mappings.length;
				for (var i:int = 0; i < len; i++) 
				{
					const mapping:IMediatorMapping = _mappings[i];
					if (mapping.matcher.matches(item))
					{
						_knownMappings[type] ||= [];
						_knownMappings[type].push(mapping);
					}
				}
				if (_knownMappings[type] === false)
				{
					return null;
				}
			}
			return _knownMappings[type] as Array;
		}
		
		/* INTERFACE xxl.robotlegs.extensions.viewmanager.api.IViewHandler */
		
		public function handleView(view:DisplayObject, type:Class):void 
		{
			const interestedMappings:Array = getInterestedMappingsFor(view, type);
			if (interestedMappings)
			{
				_factory.createMediators(view, type, interestedMappings);
			}
		}
		
	}

}